package com.lianda.json;

import com.google.gson.*;
import com.google.gson.internal.LinkedTreeMap;
import com.google.gson.internal.bind.ObjectTypeAdapter;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;

import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

//测试json转换key名
public class GsonTest {

    static Map<String, String> keyMap = new HashMap<String, String>(){{
        put("name", "MyName");
        put("age", "MyAge");
        put("kind", "MyKind");
    }};

    static Map<String, String> valueMap = new HashMap<String, String>(){{
        put("cat", "dog");
        put("123", "123dog");
    }};

    public static void main(String[] args) {
        Gson gson = new GsonBuilder()
                .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)
                .registerTypeAdapter(
                        new TypeToken<Map<String, Object>>(){}.getType(),
                        new My2TypeAdapter())
                .create();

        String str1 = "{\"name\":\"abc\",\"age\":\"123\",\"info\":[{\"message\":\"cat\",\"kind\":\"asd\"},{\"message\":\"cat\",\"kind\":\"dedsf\"}]}";

        Map<String, Object> map = null;
        long start = System.currentTimeMillis();
        for(int i = 0; i < 10000000; i++) {
            map = gson.fromJson(str1,
                    new TypeToken<Map<String, Object>>(){}.getType());
        }
        long end = System.currentTimeMillis();
        System.out.println("消耗时间" + (end -start) + "ms");

        System.out.println("====>");

    }

    static class My2TypeAdapter extends TypeAdapter<Object> {

        @Override
        public void write(JsonWriter out, Object value) throws IOException {

        }

        public Object read(JsonReader in) throws IOException {
            JsonToken token = in.peek();
            switch(token) {
                case BEGIN_ARRAY:
                    List<Object> list = new ArrayList();
                    in.beginArray();

                    while(in.hasNext()) {
                        list.add(this.read(in));
                    }

                    in.endArray();
                    return list;
                case BEGIN_OBJECT:
                    Map<String, Object> map = new LinkedTreeMap();
                    in.beginObject();

                    while(in.hasNext()) {
                        String originalName = in.nextName();
                        String newName = keyMap.get(originalName);
                        if (newName != null && !newName.equals("")) {
                            map.put(newName, this.read(in));
                        } else {
                            map.put(originalName, this.read(in));
                        }
                    }

                    in.endObject();
                    return map;
                case STRING:
                    String originalValue = in.nextString();
                    String newValue = valueMap.get(originalValue);
                    if (newValue != null && !originalValue.equals("")) {
                        return newValue;
                    } else {
                        return originalValue;
                    }
//                    return  in.nextString();
                case NUMBER:
                    //处理数字类型
                    String numberStr = in.nextString();
                    if (numberStr.contains(".") || numberStr.contains("e")
                            || numberStr.contains("E")) {
                        return Double.parseDouble(numberStr);
                    }
                    return Long.parseLong(numberStr);
                case BOOLEAN:
                    return in.nextBoolean();
                case NULL:
                    in.nextNull();
                    return null;
                default:
                    throw new IllegalStateException();
            }
        }

    }

}
